package com.sduonline.isdapp.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sduonline.isdapp.config.BaseConfig;
import com.sduonline.isdapp.config.ImageConfig;
import com.sduonline.isdapp.jdbc.ArticleDao;
import com.sduonline.isdapp.jdbc.ImageDao;
import com.sduonline.isdapp.jdbc.WebAdminDao;
import com.sduonline.isdapp.model.Article;
import com.sduonline.isdapp.model.Image;
import com.sduonline.isdapp.model.Web;
import com.sduonline.isdapp.util.ImageUtil;
import com.sduonline.isdapp.util.SHA1Utils;

public class CrawlerService {

	private ArticleDao adao = new ArticleDao();
	private WebAdminDao wadao = new WebAdminDao();
	private ImageDao imgdao = new ImageDao();

	/**
	 * 获取该网站中日期从startTime到endTime的文章
	 * 
	 * @param web
	 */
	public List<Article> execute(Web web, String startTime, String endTime) {

		List<Article> articles = null;

		System.out.println("visit web id is " + web.getId() + ",time is " + startTime + " between " + endTime);
		try {
			articles = visitArticleCrawler(web, startTime, endTime);
		} catch (IOException e) {
			System.out.println("visit Clawer Error !");
			e.printStackTrace();
			articles = null;
		} catch (NullPointerException e) {
			System.out.println("articles is null !");
			e.printStackTrace();
			articles = null;
		} catch (Exception e) {
			System.out.println("visit Clawer Error !");
			e.printStackTrace();
			articles = null;
		}

		return articles;

	}

	/**
	 * 将图片保存到本地，并将图片在本地的连接以拼接字符串的形式保存到article的imgs中
	 * 
	 * @param articles
	 * @return
	 */
	protected boolean save3Pic(List<Article> articles) {

		for (Article a : articles) {
			String content = a.getContent();
			String s = "";
			if (content != null) {
				Document doc = Jsoup.parse(content);
				Elements imgs = doc.getElementsByTag("img");
				int index = 0;
				for (Element e : imgs) {
					String attr = e.attr("src");

					// 判断图片是不是附件上的icon，目前还没想到什么好的方式，暂时用icon作为筛选条件
					if (attr.contains("/icon")) {// icon_text/zip...或/icon16...
						continue;
					}
					System.out.println("article id:" + a.getId() + ",attr:" + attr);

					// 保存图片到本地
					String suffix = attr.substring(attr.lastIndexOf(".") + 1);// 后缀
					String imgName = a.getId() + System.currentTimeMillis() + index + "." + suffix;
					String savePath = BaseConfig.ROOT + ImageConfig.imageSavePath;// 保存到服务器本地文件夹下的路径
					String link = BaseConfig.PRO_NAME + ImageConfig.imageSavePath + imgName;// 保存到数据库中的link
					boolean isSaved = ImageUtil.savePicToLocal(attr, savePath, imgName);
					if (index == 4) {
						break;
					}
					if (isSaved) {
						s += (link + ";");
						index++;
					}
				}
				a.setImgs(s);// 使用拼接字符串保存图片路径的方式

				doc = null;
				imgs = null;
			}

		}

		return true;
	}

	/**
	 * 保存articles用的service
	 * 
	 * @param articles
	 */
	protected boolean saveArticle(List<Article> articles) {

		boolean isSucceed = false;
		if (articles != null) {
			System.out.println("articles length:" + articles.size());
			isSucceed = adao.saveOrUpdateBatch(articles);
		}

		if (isSucceed) {
			System.out.println("articles save succeed.");
		} else {
			System.out.println("articles save failed.");
		}

		return isSucceed;
	}

	/**
	 * 通过接口访问并获得最新的文章
	 * 
	 * @return
	 * @throws IOException
	 */
	private List<Article> visitArticleCrawler(Web web, String startTime, String endTime) throws IOException {

		String username = wadao.getByWebId(web.getId()).getUsername();
		String interface_url = web.getInterface_url();
		int maxBodySize = 1024 * 1024 * 10;// 10M
		int timeout = 20 * 1000; // 20s

		// 尝试着动态改变这俩的值
		try {
			long st = Long.parseLong(startTime);
			long et = Long.parseLong(endTime);
			int day = (int) (et - st) / 24 / 60 / 60;
			if (day > 2) {
				maxBodySize = 1024 * 1024 * 5 * day;// 每天的max累加
				timeout = 10 * 1000 * day;// 一天给10s延迟
			}
		} catch (Exception e) {
			e.printStackTrace();
			maxBodySize = 1024 * 1024 * 10;
			timeout = 20 * 1000;
		}

		System.out.println("received maxBodySize:" + maxBodySize + ",read timeout:" + timeout);
		Response resp = Jsoup.connect(interface_url).data("startTime", startTime).data("endTime", endTime)
				.maxBodySize(maxBodySize).timeout(timeout).postDataCharset("utf-8").method(Method.POST).execute();

		System.out.println("response's charset=" + resp.charset());
		// JSONObject list = JSONObject.parseObject(new
		// String(resp.body().getBytes(
		// resp.charset() == null ? "ISO-8859-1" : resp.charset()), "UTF-8"));

		JSONObject list = JSONObject.parseObject(resp.body());

		String resp_signature = list.getString("signature");
		String resp_timestamp = list.getString("timestamp");

		List<Article> articles = null;
		System.out.println("resp_signature:" + resp_signature);
		System.out.println("username:" + username);
		System.out.println("resp_timestamp:" + resp_timestamp);
		System.out.println("*********************");

		if (checkSignature(resp_signature, username, resp_timestamp)) {
			if (list.getJSONArray("list") != null && !list.getJSONArray("list").isEmpty()) {
				articles = JSONArray.parseArray(list.getJSONArray("list").toJSONString(), Article.class);
			} else {// 如果为空的话直接返回null
				return null;
			}

			// 输出日志的这话如果不进行判断则会报错，反而影响程序
			if (list != null && !list.getJSONArray("list").isEmpty()) {
				System.out.println("title:" + list.getJSONArray("list").getObject(0, Article.class).getTitle());
				System.out.println("time:" + list.getJSONArray("list").getObject(0, Article.class).getTime());
			}

		}

		return articles;
	}

	/**
	 * username和timestamp拼接后sha1加密，然后和signature对比，相同返回true，否则返回false
	 * 
	 * @param signature
	 * @param username
	 * @param timestamp
	 * @return
	 */
	protected boolean checkSignature(String signature, String username, String timestamp) {
		String sign = SHA1Utils.SHA1((username + timestamp));// username和timestamp拼接，sha1加密
		if (sign.equals(signature)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 保存文章中的图片,尝试用直接使用文章id保存图片的方式，失败了
	 * 
	 * @param articles
	 */
	protected boolean parsePicAndSave(List<Article> articles) {

		List<Image> images = new ArrayList<>();

		for (Article a : articles) {
			String content = a.getContent();
			if (content != null) {
				Document doc = Jsoup.parse(content);
				Elements imgs = doc.getElementsByTag("img");
				int index = 1;
				for (Element e : imgs) {
					String attr = e.attr("src");
					System.out.println("article id:" + a.getId() + ",attr:" + attr);

					if (a.getId() == 0) {
						break;// 如果获取这个文章的id失败了，那么也就不需要并且没法保存这篇文章的图片了
					}
					Image img = new Image();
					img.setArticleId(a.getId());
					img.setBaseUrl(attr);
					// 保存图片到本地
					String suffix = attr.substring(attr.lastIndexOf(".") + 1);// 后缀
					String imgName = a.getId() + System.currentTimeMillis() + index + "." + suffix;
					String savePath = BaseConfig.ROOT + ImageConfig.imageSavePath;
					String link = ImageConfig.imageSavePath + imgName;
					boolean isSaved = ImageUtil.savePicToLocal(attr, savePath, imgName);
					if (isSaved) {
						img.setLink(link);
						boolean isContain = false;
						for (Image image : images) {// 检测images里是否已经包含该image
							if (img.getBaseUrl().equals(image.getBaseUrl())) {
								isContain = true;
								break;
							}
						}
						if (!isContain) {
							images.add(img);
						}
					}
					index++;
				}
			}
		}

		boolean isSaved = imgdao.saveBatch(images);
		if (isSaved) {
			System.out.println("image save success.");
		} else {
			System.out.println("image save failed.");
		}

		return isSaved;
	}

	public static void main(String[] args) throws IOException {
		Web web = new Web();
		web.setId(2);
		web.setInterface_url("http://202.194.14.197:8283/QCSD1/servlet/QcsdS");
		new CrawlerService().execute(web, "1459440000", System.currentTimeMillis() / 1000 + "");// 1462032000
	}

}
